/*
 * Copyright (C) 2005 Johan Maasing johan at zoom.nu Licensed under the Apache
 * License, Version 2.0 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law
 * or agreed to in writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the specific language
 * governing permissions and limitations under the License.
 */
package nu.zoom.swing.desktop.component.filechooser.impl;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javax.swing.JFileChooser;

import nu.zoom.swing.desktop.Workbench;
import nu.zoom.swing.desktop.common.BackendException;
import nu.zoom.swing.desktop.component.filechooser.FileChooser;
import nu.zoom.swing.desktop.component.stringmenu.StringMenu;
import nu.zoom.swing.desktop.component.stringmenu.StringMenuItem;
import nu.zoom.swing.desktop.preferences.Preferences;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * @author Johan Maasing
 */
public class FileChooserImpl implements FileChooser {
	private Log log = LogFactory.getLog(getClass());

	private RegExpFileFilter filter;

	private String preferencesKey;

	private Preferences preferences;

	private Workbench workbench;

	private StringMenu<File> menu = null;

	public FileChooserImpl(final Workbench workbench,
			final Preferences preferences, final String preferencesKey,
			final String filterDescription, final List<String> fileNamePatterns) {
		super();
		this.preferencesKey = preferencesKey;
		this.preferences = preferences;
		this.workbench = workbench;
		if ((fileNamePatterns != null) && (fileNamePatterns.size() > 0)) {
			filter = new RegExpFileFilter(filterDescription, fileNamePatterns);
		} else {
			filter = null;
		}
	}

	@Override
	public void setMenu(StringMenu<File> menu) {
		this.menu = menu;
	}

	@Override
	public File openFile() {
		log.trace("Creating file open dialog");
		JFileChooser chooser = getChooser();
		chooser.showOpenDialog(workbench.getDialogOwner());
		File file = chooser.getSelectedFile();
		saveLastDirectory(file);
		return file;
	}

	@Override
	public File saveFile() {
		log.trace("Creating file save dialog");
		JFileChooser chooser = getChooser();
		chooser.showSaveDialog(workbench.getDialogOwner());
		File file = chooser.getSelectedFile();
		saveLastDirectory(file);
		return file;
	}

	private JFileChooser getChooser() {
		log.trace("Creating a new File chooser");
		JFileChooser chooser = new JFileChooser(getLastDirectory());
		if (filter != null) {
			chooser.setFileFilter(filter);
		}
		chooser.setMultiSelectionEnabled(false);
		chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		return chooser;
	}

	private String getLastDirectory() {
		log.trace("Trying to get last opened directory from preferences using key: "
				+ preferencesKey);
		try {
			return preferences.getString(preferencesKey);
		} catch (Exception e) {
			log.error("Unable to get value from preferences", e);
			// Ignore this, this is not an essential function.
			return null;
		}
	}

	private void saveLastDirectory(File file) {
		if (file != null) {
			if (file.getParent() != null) {
				updateMenu(file);
				log.trace("Trying to save last opened directory to preferences using key: "
						+ preferencesKey);
				try {
					preferences.setString(preferencesKey, file.getParent());
				} catch (BackendException e) {
					log.error("Unable to set value in preferences", e);
					// Ignore this, this is not an essential function.
				}
			}
		}
	}

	private void updateMenu(final File file) {
		
		if (menu != null) {
			// Fallback to (possibly) non-canonical name
			String presentationName = file.toString();
			File menuFile = file ;
			try {
				menuFile = file.getCanonicalFile() ;
				presentationName = menuFile.getPath() ;
			} catch (IOException e) {
				log.warn("Unable to get canonical name for file: " + file, e);
			}
			if (presentationName.length() > 30) {
				presentationName = "..."
						+ presentationName
								.substring(presentationName.length() - 27);
			}
			StringMenuItem<File> menuItem = new StringMenuItem<File>(menuFile,
					presentationName);
			menu.removeItem(menuItem);
			menu.addItem(menuItem);
		}
	}
}
